package main

import "fmt"

func main() {
	/*
		defer 的词义：“延迟”，“推迟”
		在 go 语言中，使用 defer 关键字来延迟一个函数或者方法的执行

		1.defer 函数或方法：一个函数或方法的执行被延迟了

		2.defer 的用法：
			A: 常用于保证一些资源最后一定能够得到回收和释放
			对象.close()，临时文件的删除。。。
					文件.open()
					defer close()
					读或写

			B: Go语言中关于异常的处理，使用 panic() 和 recover()
				panic 函数用于引发恐慌，导致程序中断运行
				recover 函数用于恢复程序的执行，recover()语法上要求必须在 defer 中执行

		3.如果多个 defer 函数：先延迟的后执行，后延迟的先执行(和栈的存储一样)

		4.defer 函数传递参数的时候：defer 函数调用时，就已经传递了参数数据了，只是暂时不执行函数中的代码而已

		5.defer 函数注意点：
			（1）当外围函数中的语句正常执行完毕时，只有其中所有的延迟函数都执行完毕，外围函数才会真正地结束执行
			（2）当执行外围函数中的 return 语句时，只有其中所有的延迟函数都执行完毕后，外围函数才会真正返回
			（3）当外围函数中的代码引发运行恐慌时，只有其中所有的延迟函数都执行完毕后，该运行时恐慌才会真正被扩展至调用函数

		6.注：
			（1）defer 后面必须是函数和方法的调用
			（2）主动调用 os.Exit(int) 退出程序，defer 将不再执行
			（3）一般 defer 语句放在错误检查语句之后
			（4）defer 最好不要对有名返回值参数进行操作
	*/
	fmt.Println("美羊羊")
	fmt.Println("懒洋洋")
	defer funn()
	fmt.Println("红太狼")

	a := 2
	fmt.Println(a) //2
	defer funnx(a) //2
	a++
	fmt.Println(a) //3

}

func funn() {
	fmt.Println("喜羊羊")
	fmt.Println("灰太狼")
}

func funnx(a int) {
	fmt.Println("defer 中的a: ", a) //2
}
